<?php
namespace Modules\ShopApi\Services;
use Tymon\JWTAuth\Facades\JWTAuth;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\Exceptions\TokenInvalidException;
use EasyWeChat\Factory;
use App\Exceptions\ApiException;
use Modules\AuthAdmin\Services\CommonService;
class ShopUserService  
{
	private $tt_app_id,$tt_app_secret; 
	 public function __construct()
    {
        \Config::set('auth.defaults.guard', 'shop_user');
		\Config::set('jwt.ttl', 60);
		$this->tt_app_id = env('TT_APP_ID',''); 
		$this->tt_app_secret = env('TT_APP_SECRET',''); 
    }
	/**
     * @name  小程序获取用户所有信息
	 * @data  参数内容包含  code iv encryptData
	 * @return 返回详细用户信息
     */
    public function get_user_info($data)
    {
		if(isset($data['type']) && $data['type'] == 2){
			return $this->get_tt_user_info($data);
		}else{
			return $this->get_wx_user_info($data);
		} 
    }
	/**
     * @name  字节小程序获取用户所有信息
	 * @return 返回详细用户信息
     */
	private function get_tt_user_info($data){
		$res = $this->get_tt_user_info_s($data);
		if($res['error'] == 0){
			$arr = [
				'xcx_open_id'=>$res['openid'],
				'nick_name'=>$data['nickName'],
				'avatar_url'=>$data['avatarUrl'],
				'type'=>$data['type'],
				'created_at'=>date('Y-m-d H:i:s')
			];
			if($data['gender']==0){ 
				$arr['gender'] = 1;
			}else if($data['gender']==1){
				$arr['gender'] = 2;
			}else{
				$arr['gender'] = 0;
			}
			if(isset($res['anonymous_openid'])){
				$arr['anonymous_openid'] = $res['anonymous_openid']; 
			}
			return $arr; 
		}	
		throw new ApiException(['code'=>4444,'msg'=>'网络错误']);
	}
	/**
     * @name  字节小程序获取用户所有信息
	 * @return 返回详细用户信息
     */
	private function get_tt_user_info_s($data){
		$param = [
				'appid' => $this->tt_app_id,
				'secret'=> $this->tt_app_secret,
				'code'=>$data['code']
			];
		if(isset($data['anonymousCode']) && $data['anonymousCode']){
			$param['anonymous_code'] = $data['anonymousCode'];
		}	 
		$res = (new CommonService())->juhe_curl(
			'https://developer.toutiao.com/api/apps/jscode2session',
			$param
		);
		return json_decode($res,true); 
	}
	/**
     * @name  微信小程序获取用户所有信息
	 * @data  参数内容包含  code iv encryptData
	 * @return 返回详细用户信息
     */
	private function get_wx_user_info($data){
		$config = config('wechat.mini_program.default');
		$app = Factory::miniProgram($config);
		$new_mini = $this->mimi_code($data['code']);
		if(isset($new_mini['errcode'])){
			throw new ApiException(['code'=>$new_mini['errcode'],'msg'=>$new_mini['errmsg']]);
		}
		$decrypted_data = $app->encryptor->decryptData($new_mini['session_key'], $data['iv'],$data['encryptData']);
		return $decrypted_data;
	}
	/**
     * @name  小程序获取open_id和session_key
	 * @code  小程序code码
	 * @return 返回 session_key open_id 
     */
    public function mimi_code($code)
    {
		$config = config('wechat.mini_program.default');
		$mini = Factory::miniProgram($config);
		$new_mini = $mini->auth->session($code);
        return $new_mini;
    } 
	/**
     * @name 设置token
     */
	public function set_token($data){ 
		if (! $token = JWTAuth::attempt($data)){  
            return [];
        }
		return $this->respond_with_token($token);
	}
	/**	 
	 * @name  我的信息	 
	 */
	public function my(){
		try {
            if (! $user = JWTAuth::parseToken()->authenticate()) {  //获取到用户数据，并赋值给$user   'msg' => '用户不存在'
				throw new ApiException(['code'=>1004,'msg'=>'请先登录！']);
            }
		} catch (TokenExpiredException $e) {
			//token已过期
			throw new ApiException(['code'=>1003,'msg'=>'token 过期！']);
        } catch (TokenInvalidException $e) {
			throw new ApiException(['code'=>1002,'msg'=>'请先登录！']);
        } catch (JWTException $e) {
			//'缺少token'
			return false;
        }
		return JWTAuth::parseToken()->touser();
	}
	/**	 
	 * @name  退出登录
	 */
    public function logout()
    {
        JWTAuth::parseToken()->invalidate();
    }
	/**	 
	 * @name  绑定手机号
	 * @data  参数内容包含  code iv encryptData
	 */
    public function send_phone($data)
    {
		if(isset($data['type']) && $data['type'] == 2){
			return $this->tt_send_phone($data);
		}else{
			return $this->wx_send_phone($data);
		}
    }
	/**	 
	 * @name  头条绑定手机号
	 * @data  参数内容包含  code iv encryptData
	 */ 
    private function tt_send_phone($data){
		$res = $this->get_tt_user_info_s($data);
		if($res['error'] == 0){  
			return $this->decryptData( $res['session_key'],$data['encryptData'], $data['iv'],$this->tt_app_id);
		} 
		throw new ApiException(['code'=>4444,'msg'=>'网络错误！']);
	} 
	/**	 
	 * @name  微信绑定手机号
	 * @data  参数内容包含  code iv encryptData
	 */
    public function wx_send_phone($data){
		$config = config('wechat.mini_program.default');
		$new_mini = $this->mimi_code($data['code']);
		if(isset($new_mini['errcode'])){
			throw new ApiException(['code'=>$new_mini['errcode'],'msg'=>$new_mini['errmsg']]);
		}
		return $this->decryptData($new_mini['session_key'],$data['encryptData'],$data['iv'],$config['app_id']); 
	}
	/**
	 * 检验数据的真实性，并且获取解密后的明文.
	 * @return array
	 */
	private function decryptData($sessionKey,$encryptedData,$iv,$appid)
	{
		if (strlen($sessionKey) != 24) {
			throw new ApiException(['code'=>4444,'msg'=>'失败1！']);
		} 
		$aesKey=base64_decode($sessionKey);
		if (strlen($iv) != 24) {
			throw new ApiException(['code'=>4444,'msg'=>'失败2！']);
		}
		$aesIV=base64_decode($iv);
		
		$aesCipher=base64_decode($encryptedData); 
 
		$result = openssl_decrypt( $aesCipher, "AES-128-CBC", $aesKey, OPENSSL_RAW_DATA, $aesIV);  
		$dataObj=json_decode( $result );
		return $result;
		if( $dataObj  == NULL )
		{
			throw new ApiException(['code'=>4444,'msg'=>'失败！']);
		}
		if( $dataObj->watermark->appid != $appid )
		{
			throw new ApiException(['code'=>4444,'msg'=>'失败！']);
		}
		return $result;
	}
	/**	 
	 * @name  刷新	 
	 */
    public function refresh()
    {
        return $this->respond_with_token(JWTAuth::parseToken()->refresh());
    }	
	/**
     * @name 组合token数据
     */
	protected function respond_with_token($token)
    {
        return [
				'token' => $token,
				'token_type' => 'bearer',
				'expires_in' => JWTAuth::factory()->getTTL() * 60
			];
    }
	/**
     * @name  获取商品小程序码
	 * @param  id string 小程序链接
	 * @param  width int 二维码宽度
	 * @return string
     */
    public function get_app_code($url,$width = 150)
    {
		$CommonService = new CommonService();
		$thhp = $CommonService->get_http_type();
		$date = date('Ymd');
		$make_order_no = $CommonService->make_order_no();
		$config = config('wechat.mini_program.default');
		$app = Factory::miniProgram($config);
		$response = $app->app_code->get($url, [
			'width' => $width
		]);
		if ($response instanceof \EasyWeChat\Kernel\Http\StreamResponse) {
			return $thhp.'/app_code/'.$date.'/'.$response->save(public_path('app_code/'.$date),$make_order_no.'.png');
		}else{
			throw new ApiException(['code'=>4444,'msg'=>'二维码生成失败！']);
		}
    } 
}
